home *** CD-ROM | disk | FTP | other *** search
/ OpenGL Superbible (2nd Edition) / OpenGL SuperBible e2.iso / tools / GLUT-3.7 / PROGS / mesademos / TR.C < prev    next >
Encoding:
C/C++ Source or Header  |  1998-08-12  |  5.4 KB  |  237 lines

  1.  
  2. /* tr.c */
  3.  
  4. /*
  5.  * Tiled Rendering library
  6.  *
  7.  * Brian Paul
  8.  * April 1997
  9.  */
  10.  
  11.  
  12. #include <assert.h>
  13. #include <math.h>
  14. #include <stdlib.h>
  15.  
  16. #include "tr.h"
  17.  
  18.  
  19.  
  20. struct _TRctx {
  21.    GLint ImageWidth, ImageHeight;
  22.    GLubyte *Image;
  23.  
  24.    GLint TileWidth, TileHeight;
  25.  
  26.    GLboolean Perspective;
  27.    GLdouble Left;
  28.    GLdouble Right;
  29.    GLdouble Bottom;
  30.    GLdouble Top;
  31.    GLdouble Near;
  32.    GLdouble Far;
  33.  
  34.    GLint Rows, Columns;
  35.    GLint CurrentTile;
  36.    GLint CurrentTileWidth, CurrentTileHeight;
  37.    GLint CurrentRow, CurrentColumn;
  38.  
  39.    GLint ViewportSave[4];
  40. };
  41.  
  42.  
  43.  
  44. TRcontext *trNew(void)
  45. {
  46.    return (TRcontext *) calloc(1, sizeof(TRcontext));
  47. }
  48.  
  49.  
  50. void trDelete(TRcontext *tr)
  51. {
  52.    if (tr)
  53.       free(tr);
  54. }
  55.  
  56.  
  57. void trSetup(TRcontext *tr,
  58.          GLint imageWidth, GLint imageHeight, GLubyte *image,
  59.          GLint tileWidth, GLint tileHeight)
  60. {
  61.    if (!tr || !image)
  62.       return;
  63.  
  64.    tr->ImageWidth = imageWidth;
  65.    tr->ImageHeight = imageHeight;
  66.    tr->Image = image;
  67.    tr->TileWidth = tileWidth;
  68.    tr->TileHeight = tileHeight;
  69.  
  70.    tr->Columns = (tr->ImageWidth + tr->TileWidth - 1) / tr->TileWidth;
  71.    tr->Rows = (tr->ImageHeight + tr->TileHeight - 1) / tr->TileHeight;
  72.    tr->CurrentTile = 0;
  73.  
  74.    assert(tr->Columns >= 1);
  75.    assert(tr->Rows >= 1);
  76. }
  77.  
  78.  
  79. void trOrtho(TRcontext *tr,
  80.          GLdouble left, GLdouble right,
  81.          GLdouble bottom, GLdouble top,
  82.          GLdouble nnear, GLdouble ffar)
  83. {
  84.    if (!tr)
  85.       return;
  86.  
  87.    tr->Perspective = GL_FALSE;
  88.    tr->Left = left;
  89.    tr->Right = right;
  90.    tr->Bottom = bottom;
  91.    tr->Top = top;
  92.    tr->Near = nnear;
  93.    tr->Far = ffar;
  94.    tr->CurrentTile = 0;
  95. }
  96.  
  97.  
  98. void trFrustum(TRcontext *tr,
  99.            GLdouble left, GLdouble right,
  100.            GLdouble bottom, GLdouble top,
  101.            GLdouble zNear, GLdouble zFar)
  102. {
  103.    if (!tr)
  104.       return;
  105.  
  106.    tr->Perspective = GL_TRUE;
  107.    tr->Left = left;
  108.    tr->Right = right;
  109.    tr->Bottom = bottom;
  110.    tr->Top = top;
  111.    tr->Near = zNear;
  112.    tr->Far = zFar;
  113.    tr->CurrentTile = 0;
  114. }
  115.  
  116.  
  117. void trPerspective(TRcontext *tr,
  118.            GLdouble fovy, GLdouble aspect,
  119.            GLdouble zNear, GLdouble zFar )
  120. {
  121.    GLdouble xmin, xmax, ymin, ymax;
  122.    ymax = zNear * tan(fovy * 3.14159265 / 360.0);
  123.    ymin = -ymax;
  124.    xmin = ymin * aspect;
  125.    xmax = ymax * aspect;
  126.    trFrustum(tr, xmin, xmax, ymin, ymax, zNear, zFar);
  127. }
  128.  
  129.  
  130. void trBeginTile(TRcontext *tr)
  131. {
  132.    GLint matrixMode;
  133.    int tileWidth, tileHeight;
  134.    GLdouble left, right, bottom, top;
  135.  
  136.    if (!tr)
  137.       return;
  138.  
  139.    if (tr->CurrentTile==0) {
  140.       /* Save user's viewport, will be restored after last tile rendered */
  141.       glGetIntegerv(GL_VIEWPORT, tr->ViewportSave);
  142.    }
  143.  
  144.    /* which tile (by row and column) we're about to render */
  145.    tr->CurrentRow = tr->CurrentTile / tr->Columns;
  146.    tr->CurrentColumn = tr->CurrentTile % tr->Columns;
  147.  
  148.    /* actual size of this tile */
  149.    if (tr->CurrentRow < tr->Rows-1)
  150.       tileHeight = tr->TileHeight;
  151.    else
  152.       tileHeight = tr->ImageHeight - (tr->Rows-1) * tr->TileHeight;
  153.  
  154.    if (tr->CurrentColumn < tr->Columns-1)
  155.       tileWidth = tr->TileWidth;
  156.    else
  157.       tileWidth = tr->ImageWidth - (tr->Columns-1) * tr->TileWidth;
  158.  
  159.  
  160.    tr->CurrentTileWidth = tileWidth;
  161.    tr->CurrentTileHeight = tileHeight;
  162.  
  163.    glViewport(0, 0, tileWidth, tileHeight);
  164.  
  165.    /* save current matrix mode */
  166.    glGetIntegerv(GL_MATRIX_MODE, &matrixMode);
  167.    glMatrixMode(GL_PROJECTION);
  168.    glLoadIdentity();
  169.  
  170.    /* compute projection parameters */
  171.    left = tr->Left + (tr->Right - tr->Left)
  172.         * (tr->CurrentColumn * tr->TileWidth) / tr->ImageWidth;
  173.    right = left + (tr->Right - tr->Left) * tileWidth / tr->ImageWidth;
  174.    bottom = tr->Bottom + (tr->Top - tr->Bottom)
  175.           * (tr->CurrentRow * tr->TileHeight) / tr->ImageHeight;
  176.    top = bottom + (tr->Top - tr->Bottom) * tileHeight / tr->ImageHeight;
  177.  
  178.    if (tr->Perspective)
  179.       glFrustum(left, right, bottom, top, tr->Near, tr->Far);
  180.    else
  181.       glOrtho(left, right, bottom, top, tr->Near, tr->Far);
  182.  
  183.    /* restore user's matrix mode */
  184.    glMatrixMode(matrixMode);
  185. }
  186.  
  187.  
  188.  
  189. int trEndTile(TRcontext *tr)
  190. {
  191.    GLint prevRowLength, prevSkipRows, prevSkipPixels, prevAlignment;
  192.    GLint x, y;
  193.  
  194.    if (!tr)
  195.       return 0;
  196.  
  197.    /* be sure OpenGL rendering is finished */
  198.    glFlush();
  199.  
  200.    /* save current glPixelStore values */
  201.    glGetIntegerv(GL_PACK_ROW_LENGTH, &prevRowLength);
  202.    glGetIntegerv(GL_PACK_SKIP_ROWS, &prevSkipRows);
  203.    glGetIntegerv(GL_PACK_SKIP_PIXELS, &prevSkipPixels);
  204.    glGetIntegerv(GL_PACK_ALIGNMENT, &prevAlignment);
  205.  
  206.    x = tr->TileWidth * tr->CurrentColumn;
  207.    y = tr->TileHeight * tr->CurrentRow;
  208.  
  209.    /* setup pixel store for glReadPixels */
  210.    glPixelStorei(GL_PACK_ROW_LENGTH, tr->ImageWidth);
  211.    glPixelStorei(GL_PACK_SKIP_ROWS, y);
  212.    glPixelStorei(GL_PACK_SKIP_PIXELS, x);
  213.    glPixelStorei(GL_PACK_ALIGNMENT, 1);
  214.  
  215.    /* read the tile into the final image */
  216.    glReadPixels(0, 0, tr->CurrentTileWidth, tr->CurrentTileHeight,
  217.         GL_RGBA, GL_UNSIGNED_BYTE, tr->Image);
  218.  
  219.    /* restore previous glPixelStore values */
  220.    glPixelStorei(GL_PACK_ROW_LENGTH, prevRowLength);
  221.    glPixelStorei(GL_PACK_SKIP_ROWS, prevSkipRows);
  222.    glPixelStorei(GL_PACK_SKIP_PIXELS, prevSkipPixels);
  223.    glPixelStorei(GL_PACK_ALIGNMENT, prevAlignment);
  224.  
  225.    /* increment tile counter, return 1 if more tiles left to render */
  226.    tr->CurrentTile++;
  227.    if (tr->CurrentTile >= tr->Rows * tr->Columns) {
  228.       /* restore user's viewport */
  229.       glViewport(tr->ViewportSave[0], tr->ViewportSave[1],
  230.          tr->ViewportSave[2], tr->ViewportSave[3]);
  231.       return 0;
  232.    }
  233.    else
  234.       return 1;
  235. }
  236.  
  237.